<template>
  <!-- 上方卡片 -->
  <el-card>
    <el-form class="form">
      <el-form-item :inline="true" label="用户名:">
        <el-input placeholder="请输入用户名" v-model="search"></el-input>
      </el-form-item>
      <el-form-item>
        <el-button
          type="primary"
          size="default"
          :disabled="search ? false : true"
          @click="handleSearch"
        >
          搜索
        </el-button>
        <el-button type="primary" size="default" @click="handleRefresh">重置</el-button>
      </el-form-item>
    </el-form>
  </el-card>
  <!-- 下方卡片 -->
  <el-card style="margin: 30px 0px">
    <!-- 按钮 -->
    <el-button type="primary" size="default" @click="handleAdd">添加</el-button>
    <el-popconfirm title="你确定要删除已勾选的用户吗？" @confirm="handleDeleteUsers">
      <template #reference>
        <el-button type="primary" size="default">批量删除</el-button>
      </template>
    </el-popconfirm>
    <!-- 数据显示界面 -->
    <el-table border :data="userArr" style="margin: 20px 0px" @selection-change="handleSelect">
      <el-table-column type="selection" align="center"></el-table-column>
      <el-table-column type="index" label="#" align="center"></el-table-column>
      <el-table-column label="ID" align="center" prop="id"></el-table-column>
      <el-table-column label="用户名字" align="center" prop="username"></el-table-column>
      <el-table-column label="用户名称" align="center" prop="name"></el-table-column>
      <el-table-column label="用户角色" align="center" prop="roleName"></el-table-column>
      <el-table-column label="创建时间" align="center" prop="createTime"></el-table-column>
      <el-table-column label="更新时间" align="center" prop="updateTime"></el-table-column>
      <el-table-column label="操作" align="center" width="400px">
        <!-- eslint-disable -->
        <template #="{ row, $index }">
          <el-button type="primary" size="small" icon="User" @click="handleRole(row)">
            分配角色
          </el-button>
          <el-button type="primary" size="small" icon="Edit" @click="handleEdit(row)">
            编辑
          </el-button>
          <el-popconfirm :title="`你确定要删除账号${row.name}吗？`" @confirm="handleDelete(row)">
            <template #reference>
              <el-button type="primary" size="small" icon="Delete">删除</el-button>
            </template>
          </el-popconfirm>
        </template>
      </el-table-column>
    </el-table>
    <!-- 分页器 -->
    <el-pagination
      v-model:current-page="pageNo"
      @current-change="getUser"
      @size-change="handleSizeChange"
      v-model:page-size="pageSize"
      :page-sizes="[5, 7, 9, 11]"
      :background="true"
      layout="prev, pager, next, jumper,->,total, sizes"
      :total="total"
    />
    <!-- 用户添加/修改界面 -->
    <el-drawer v-model="drawer" direction="rtl">
      <template #header>
        <h4>{{ userParams.id ? '修改用户' : '添加用户' }}</h4>
      </template>
      <template #default>
        <el-form ref="refForm" :model="userParams" :rules="rules">
          <el-form-item label="用户姓名" prop="username">
            <el-input placeholder="请填写用户姓名" v-model="userParams.username"></el-input>
          </el-form-item>
          <el-form-item label="用户昵称" prop="name">
            <el-input placeholder="请填写用户昵称" v-model="userParams.name"></el-input>
          </el-form-item>
          <el-form-item v-show="userParams.id ? false : true" label="用户密码" prop="password">
            <el-input placeholder="请填写用户密码" v-model="userParams.password"></el-input>
          </el-form-item>
        </el-form>
      </template>
      <template #footer>
        <div style="flex: auto">
          <el-button @click="cancelClick">取消</el-button>
          <el-button type="primary" @click="confirmClick">确定</el-button>
        </div>
      </template>
    </el-drawer>
    <!-- 角色分配界面 -->
    <el-drawer v-model="drawer2" direction="rtl">
      <template #header>
        <h4>职位分配</h4>
      </template>
      <template #default>
        <el-form>
          <el-form-item label="用户姓名">
            <el-input v-model="userParams.username" :disabled="true"></el-input>
          </el-form-item>
          <el-form-item label="职位">
            <el-checkbox
              v-model="checkAll"
              @change="handleCheckAll"
              :indeterminate="isIndeterminate"
            >
              全选
            </el-checkbox>
            <el-checkbox-group v-model="userRole" @change="handleCheck">
              <el-checkbox v-for="(item, index) in allRole" :key="index" :label="item">
                {{ item.roleName }}
              </el-checkbox>
            </el-checkbox-group>
          </el-form-item>
        </el-form>
      </template>
      <template #footer>
        <div style="flex: auto">
          <el-button @click="cancelAssign()">取消</el-button>
          <el-button type="primary" @click="confirmAssign()">确定</el-button>
        </div>
      </template>
    </el-drawer>
  </el-card>
</template>

<script setup lang="ts">
import useLayoutSettingStore from '@/store/modules/setting'
import { ElMessage } from 'element-plus'
import { ref, onMounted, reactive, nextTick } from 'vue'
//获取接口
import {
  reqGetUser,
  reqAddOrUpdateUser,
  reqAllRole,
  reqSetRole,
  reqDeleteUser,
  reqDeleteUsers,
} from '@/api/acl/user/index'
//获取ts数据类型
import { User, Role } from '@/api/acl/user/type'
//当前页数
let pageNo = ref<number>(1)
//每页显示信息数
let pageSize = ref<number>(5)
//当前数据数
let total = ref<number>(1)
//储存用户账号信息
let userArr = ref<User[]>([])
//控制添加用户界面的显示
let drawer = ref<boolean>(false)
//收集用户信息的响应式数据
let userParams = reactive<User>({
  username: '',
  name: '',
  password: '',
})
//获取form组件实例
let refForm = ref<any>()
//控制角色分配界面的显示
let drawer2 = ref<boolean>(false)
//控制角色分配复选框是否全选
let checkAll = ref<boolean>(false)
//可选职位数组
let allRole = ref<Role[]>([])
//已选职位数组
let userRole = ref<Role[]>([])
//设置全选按钮的不确定状态
const isIndeterminate = ref<boolean>(true)
//勾选用户的id数组
let userIdList = ref<number[]>([])
//搜索内容
let search = ref<string>('')
//setting仓库的实例
let layoutSettingStore = useLayoutSettingStore()

onMounted(() => {
  getUser()
})
//获取账号信息
const getUser = async (pager = 1) => {
  pageNo.value = pager
  let result = await reqGetUser(pageNo.value, pageSize.value, search.value)
  if (result.code === 200) {
    userArr.value = result.data.userList
    total.value = result.data.total
  } else {
    ElMessage({
      type: 'error',
      message: '获取账号信息失败',
    })
  }
}
//页面展示数变化的回调
const handleSizeChange = () => {
  getUser()
}
//添加账号
const handleAdd = () => {
  drawer.value = !drawer.value
  Object.assign(userParams, {
    username: '',
    name: '',
    password: '',
    id: '',
  })
  //清除上一次的错误提示信息(表单验证)
  nextTick(() => {
    refForm.value.clearValidate('username')
    refForm.value.clearValidate('name')
    refForm.value.clearValidate('password')
  })
}
//修改账号
const handleEdit = (row: User) => {
  drawer.value = !drawer.value
  Object.assign(userParams, row)
  //清除上一次的错误提示信息(表单验证)
  nextTick(() => {
    refForm.value.clearValidate('username')
    refForm.value.clearValidate('name')
    refForm.value.clearValidate('password')
  })
}
//取消的回调
const cancelClick = () => {
  drawer.value = !drawer.value
  Object.assign(userParams, {
    username: '',
    name: '',
    password: '',
  })
}
//确定的回调
const confirmClick = async () => {
  //点击确定时进行表单验证，await返回成功参数才进行下一步
  await refForm.value.validate()
  // 后台也有校验功能，所以随便输入的账号密码也不会直接添加
  let result = await reqAddOrUpdateUser(userParams)
  if (result.code === 200) {
    ElMessage({
      type: 'success',
      message: userParams.id ? '更新成功' : '添加成功',
    })
    getUser(userParams.id ? pageNo.value : 1)
    //浏览器自动刷新一次，再检验一次账号是否有效
    window.location.reload()
  } else {
    ElMessage({
      type: 'error',
      message: userParams.id ? '更新失败' : '添加失败',
    })
  }
  drawer.value = !drawer.value
}
//校验用户名字的回调函数
///@ts-ignore
const validatorUsername = (rule, value, callBack) => {
  if (value.trim().length >= 5) {
    callBack()
  } else {
    callBack(new Error('用户名字至少五位'))
  }
}
//@ts-ignore
const validatorName = (rule, value, callBack) => {
  if (value.trim().length >= 5) {
    callBack()
  } else {
    callBack(new Error('用户昵称至少五位'))
  }
}
//@ts-ignore
const validatorPassword = (rule, value, callBack) => {
  if (value.trim().length >= 6) {
    callBack()
  } else {
    callBack(new Error('用户密码至少六位'))
  }
}
//表单校验规则对象
const rules = {
  //用户名字
  username: [{ required: true, trigger: 'blur', validator: validatorUsername }],
  name: [{ required: true, trigger: 'blur', validator: validatorName }],
  password: [{ required: true, trigger: 'blur', validator: validatorPassword }],
}
//分配角色
const handleRole = async (row: User) => {
  let result = await reqAllRole(row.id)
  if (result.code === 200) {
    drawer2.value = !drawer2.value
    Object.assign(userParams, row)
    userRole.value = result.data.assignRoles
    allRole.value = result.data.allRolesList
  } else {
    ElMessage({
      type: 'error',
      message: '获取职位信息失败',
    })
  }
}
//全选复选框的change事件
const handleCheckAll = (val: boolean) => {
  userRole.value = val ? allRole.value : []
  //设置不确定状态
  isIndeterminate.value = false
}
//底部复选框的change事件
const handleCheck = (val: string[]) => {
  //比较已勾选选项的长度确定checkAll是否勾选
  checkAll.value = val.length === allRole.value.length
  //设置不确定状态
  isIndeterminate.value = !(val.length === allRole.value.length)
}
//取消分配
const cancelAssign = () => {
  drawer2.value = !drawer2.value
}
//确定分配
const confirmAssign = async () => {
  let data = {
    userId: userParams.id,
    roleIdList: userRole.value.map((item) => item.id),
  }
  let result = await reqSetRole(data)
  if (result.code === 200) {
    ElMessage({
      type: 'success',
      message: '分配成功',
    })
    getUser(pageNo.value)
  } else {
    ElMessage({
      type: 'error',
      message: '分配失败',
    })
  }
  drawer2.value = !drawer2.value
}
//删除单个用户
const handleDelete = async (row: User) => {
  let result = await reqDeleteUser(row.id)
  if (result.code === 200) {
    ElMessage({
      type: 'success',
      message: '删除成功',
    })
    getUser(pageNo.value)
  } else {
    ElMessage({
      type: 'error',
      message: '删除失败',
    })
  }
}
//获取table勾选用户id列表
const handleSelect = (val: User[]) => {
  userIdList.value = val.map((item) => item.id)
}
//删除多个用户
const handleDeleteUsers = async () => {
  let result = await reqDeleteUsers(userIdList.value)
  if (result.code === 200) {
    ElMessage({
      type: 'success',
      message: '删除成功',
    })
    getUser(pageNo.value)
  } else {
    ElMessage({
      type: 'error',
      message: '删除失败',
    })
  }
}
//搜索用户
const handleSearch = () => {
  getUser()
  search.value = ''
}
//重置界面
const handleRefresh = () => {
  layoutSettingStore.refresh = !layoutSettingStore.refresh
}
</script>

<style scoped lang="scss">
.form {
  display: flex;
  justify-content: space-between;
  align-items: center;
}
</style>
